package com.example.demo.service;


import com.example.demo.exception.BusinessException;
import com.example.demo.exception.ResourceNotFoundException;
import com.example.demo.model.Assignment;
import com.example.demo.model.StudentAssignment;
import com.example.demo.repository.AssignmentRepository;
import com.example.demo.repository.CourseRepository;
import com.example.demo.repository.StudentAssignmentRepository;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import static sun.java2d.SurfaceData.convertTo;

@Service
@RequiredArgsConstructor
public class AssignmentService {
    private final AssignmentRepository assignmentRepository;
    private final StudentAssignmentRepository studentAssignmentRepository;
    private final CourseRepository courseRepository;
    private final FileStorageService fileStorageService;
    private final ModelMapper modelMapper;

    // 获取课程所有作业（教师端）
    public List<Assignment> getAssignmentsByCourse(Long courseId) {
        return assignmentRepository.findByCourseId(courseId).stream()
                .map(this::convertTo)
                .collect(Collectors.toList());
    }

    // 获取学生可见的作业（学生端）
    public List<Assignment> getStudentAssignments(Long courseId, Long studentId) {
        return assignmentRepository.findByCourseIdAndStudentId(courseId, studentId).stream()
                .map(assignment -> {
                    Assignment  c = convertTo(assignment);
                    // 添加学生提交状态
                    studentAssignmentRepository.findByAssignmentIdAndStudentId(assignment.getId(), studentId)
                            .ifPresent(sa -> {
                                 c.setSubmissionStatus(sa.getStatus().name());
                                 c.setSubmittedAt(sa.getSubmittedAt());
                                 c.setGrade(sa.getGrade());
                            });
                    return  ;
                })
                .collect(Collectors.toList());
    }

    // 学生提交作业
    @Transactional
    public void submitAssignment(Long studentId, Long assignmentId, AssignmentSubmission submission ) {
        Assignment assignment = assignmentRepository.findById(assignmentId)
                .orElseThrow(() -> new ResourceNotFoundException("作业不存在"));

        // 检查截止时间
        if (assignment.getDeadline() != null && assignment.getDeadline().isBefore(LocalDateTime.now())) {
            throw new BusinessException("已超过作业提交截止时间");
        }

        StudentAssignment studentAssignment = studentAssignmentRepository
                .findByAssignmentIdAndStudentId(assignmentId, studentId)
                .orElseGet(() -> createNewSubmission(studentId, assignmentId));

        studentAssignment.setContent(submission .getContent());

        // 处理附件上传
        if (submission .getAttachment() != null && !submission .getAttachment().isEmpty()) {
            String attachmentUrl = fileStorageService.storeFile(submission .getAttachment());
            studentAssignment.setAttachmentUrl(attachmentUrl);
        }

        studentAssignment.setStatus(StudentAssignment.SubmissionStatus.SUBMITTED);
        studentAssignmentRepository.save(studentAssignment);
    }

    // 教师批改作业
    @Transactional
    public void gradeAssignment(Long submissionId, GradeAssignment  grade ) {
        StudentAssignment submission = studentAssignmentRepository.findById(submissionId)
                .orElseThrow(() -> new ResourceNotFoundException("作业提交记录不存在"));

        if (submission.getStatus() != StudentAssignment.SubmissionStatus.SUBMITTED) {
            throw new BusinessException("只能批改已提交的作业");
        }

        submission.setGrade(grade .getGrade());
        submission.setFeedback(grade .getFeedback());
        submission.setStatus(StudentAssignment.SubmissionStatus.GRADED);
        studentAssignmentRepository.save(submission);
    }

    // 获取作业的所有学生提交
    public List<StudentAssignment > getAssignmentSubmissions(Long assignmentId) {
        return studentAssignmentRepository.findByAssignmentId(assignmentId).stream()
                .map(this::convertToStudentAssignment )
                .collect(Collectors.toList());
    }

    // 获取学生的作业提交详情
    public StudentAssignment  getStudentAssignment(Long studentId, Long assignmentId) {
        return studentAssignmentRepository.findByAssignmentIdAndStudentId(assignmentId, studentId)
                .map(this::convertToStudentAssignment )
                .orElseThrow(() -> new ResourceNotFoundException("作业提交记录不存在"));
    }

    private StudentAssignment createNewSubmission(Long studentId, Long assignmentId) {
        StudentAssignment submission = new StudentAssignment();

        Assignment assignment = new Assignment();
        assignment.setId(assignmentId);
        submission.setAssignment(assignment);

        User student = new User();
        student.setId(studentId);
        submission.setStudent(student);

        return submission;
    }

    private Assignment  convertTo (Assignment assignment) {
        Assignment   c = modelMapper.map(assignment, Assignment .class);
         c.setCourseId(assignment.getCourse().getId());
         c.setCourseTitle(assignment.getCourse().getTitle());
        return  c;
    }

    private StudentAssignment  convertToStudentAssignment (StudentAssignment submission) {
        StudentAssignment   a = modelMapper.map(submission, StudentAssignment .class);
        a.setAssignmentId(submission.getAssignment().getId());
         a.setAssignmentTitle(submission.getAssignment().getTitle());
         a.setStudentId(submission.getStudent().getId());
        a.setStudentName(submission.getStudent().getUsername());
        return  a;a
    }
    // AssignmentService.java 补充方法

    @Transactional(readOnly = true)
    public AssignmentStatistics  getAssignmentStatistics(Long assignmentId, Long teacherId) {
        Assignment assignment = assignmentRepository.findById(assignmentId)
                .orElseThrow(() -> new ResourceNotFoundException("作业不存在"));

        // 验证教师权限
        if (!assignment.getCourse().getTeacher().getId().equals(teacherId)) {
            throw new BusinessException("您没有权限查看此作业统计");
        }

        AssignmentStatistics  stats = new AssignmentStatistics ();
        stats.setAssignmentId(assignmentId);
        stats.setAssignmentTitle(assignment.getTitle());
        stats.setTotalStudents(studentAssignmentRepository.countByAssignmentId(assignmentId));
        stats.setSubmittedStudents((int) studentAssignmentRepository.countSubmittedStudents(assignmentId));
        stats.setGradedStudents((int)studentAssignmentRepository.countGradedStudents(assignmentId));

        // 计算平均分
        Double avgGrade = studentAssignmentRepository.calculateAverageGrade(assignmentId);
        stats.setAverageGrade(avgGrade != null ? avgGrade : 0.0);

        // 最高分和最低分
        stats.setHighestGrade(studentAssignmentRepository.findMaxGrade(assignmentId));
        stats.setLowestGrade(studentAssignmentRepository.findMinGrade(assignmentId));

        return stats;
    }

    @Transactional
    public void bulkGradeAssignments(Long assignmentId, List<BulkGrade> grades, Long teacherId) {
        Assignment assignment = assignmentRepository.findById(assignmentId)
                .orElseThrow(() -> new ResourceNotFoundException("作业不存在"));

        // 验证教师权限
        if (!assignment.getCourse().getTeacher().getId().equals(teacherId)) {
            throw new BusinessException("您没有权限批改此作业");
        }

        for (BulkGrade grade  : grades) {
            StudentAssignment submission = studentAssignmentRepository.findById(grade .getSubmissionId())
                    .orElseThrow(() -> new ResourceNotFoundException("作业提交记录不存在"));

            if (!submission.getAssignment().getId().equals(assignmentId)) {
                throw new BusinessException("提交记录与作业不匹配");
            }

            submission.setGrade(grade .getGrade());
            submission.setFeedback(grade .getFeedback());
            submission.setStatus(StudentAssignment.SubmissionStatus.GRADED);
            studentAssignmentRepository.save(submission);
        }
    }
}